#!/bin/python
# coding=utf-8
# date:2025/8/29
import configparser
import os
from pathlib import Path
from typing import Optional, Callable

from PyQt5.QtCore import QStringListModel, Qt
from PyQt5.QtWidgets import QMessageBox, QWidget, QHBoxLayout, QLineEdit, QPushButton, QCompleter


def showMessageBox(msg):
    # 使用 QMessageBox 显示一个提示框
    QMessageBox.information(None, '提示', msg)


class NoFilterCompleter(QCompleter):
    """不过滤，永远返回完整列表"""

    def splitPath(self, path: str):
        # 返回空列表 -> Qt 认为“无过滤关键字”，于是显示全部
        return []


class CustomLineEdit(QWidget):
    """
    一个带下拉列表的输入框组件。
    用户回车或点击 ▼ 按钮均可触发/收起下拉列表。
    支持把输入内容自动加入历史列表，并可通过点击列表项回填。
    内部使用 QCompleter 实现下拉，避免被其它控件遮挡。
    """

    # region 常量
    _ARROW_BTN_WIDTH: int = 30

    # endregion

    def __init__(self,
                 title=None,
                 parent: Optional[QWidget] = None,
                 width: int = 250,
                 height: int = 30,
                 callback: Optional[Callable[[], None]] = None) -> None:
        super().__init__(parent)
        self._title = title
        self._width: int = width
        self._height: int = height
        self._callback: Optional[Callable[[], None]] = callback
        self._rcd_file = ".recent"
        self._cfg = None
        # 历史记录列表
        self._history: list[str] = []
        self.load_history()
        self._build_ui()
        self._bind_signals()

    def create_ini_sample(self, path: str) -> None:
        """
        新建一个示例 INI 文件
        :param path: 目标文件名
        :param exist_ok: False -> 文件已存在则抛 FileExistsError
        """
        p = Path(path)
        self._cfg = configparser.ConfigParser()
        # 允许保留原始大小写（可选）
        self._cfg.optionxform = str
        if p.exists():
            self._cfg.read(path, encoding="utf-8-sig")

        # 2. 创建新的问题
        with p.open("w", encoding="utf-8") as f:
            self._cfg.write(f)

        print(f"已生成 {p.absolute()}")

    # ---------- 2. 写入 ----------
    def save_ini(self) -> None:
        """原子写：先写临时文件，再替换"""
        tmp = f"{self._rcd_file}.tmp"
        with open(tmp, "w", encoding="utf-8") as f:
            self._cfg.write(f)
        os.replace(tmp, self._rcd_file)

    def update_key(self, section: str, key: str, value: str) -> None:
        """section/key 不存在会自动创建"""
        if not self._cfg.has_section(section):
            self._cfg.add_section(section)
        self._cfg.set(section, key, str(value))
        self.save_ini()

    def load_history(self):
        # 根据self._title加载历史的搜索记录
        self.create_ini_sample(self._rcd_file)
        try:
            his_values = self._cfg.get("recent", self._title)
            self._history = his_values.split(',')
        except Exception as e:
            pass

    # region 构造 UI
    def _build_ui(self) -> None:
        self.setFixedSize(self._width, self._height)
        self.setStyleSheet("font-size: 14px;")

        # 主布局
        self._main_layout = QHBoxLayout(self)
        self._main_layout.setContentsMargins(0, 0, 0, 0)
        self._main_layout.setSpacing(0)

        # 输入框
        self._line_edit = QLineEdit()
        self._line_edit.setPlaceholderText("请输入查询内容...")
        self._line_edit.setFixedHeight(self._height)
        self._line_edit.setFixedWidth(self._width - self._ARROW_BTN_WIDTH)

        # 按钮
        self._arrow_btn = QPushButton("▼")
        self._arrow_btn.setFixedSize(self._ARROW_BTN_WIDTH, self._height)
        self._arrow_btn.setStyleSheet("padding: 0px; margin: 0px;")

        self._main_layout.addWidget(self._line_edit)
        self._main_layout.addWidget(self._arrow_btn)

        # QCompleter
        self._completer = NoFilterCompleter(self)
        self._completer.setCaseSensitivity(Qt.CaseInsensitive)
        self._completer.setFilterMode(Qt.MatchContains)
        self._completer.setCompletionMode(QCompleter.PopupCompletion)
        self._line_edit.setCompleter(self._completer)

        # 数据模型
        self._model = QStringListModel(self)
        self._model.setStringList(self._history)
        self._completer.setModel(self._model)

    # endregion

    # region 信号绑定
    def _bind_signals(self) -> None:
        # 点击按钮触发自动补全下拉
        self._arrow_btn.clicked.connect(self._show_completer_popup)
        self._line_edit.returnPressed.connect(self._on_return_pressed)
        # ↓↓↓ 新增：选中条目时的统一入口 ↓↓↓
        self._completer.activated.connect(self._on_item_selected)

    # endregion
    def _on_item_selected(self, text: str):
        """
        用户在下拉列表里回车或鼠标点击都会走到这里
        text：选中的那一项字符串
        """
        self._line_edit.setText(text)  # 回填
        if self._callback:
            self._callback()  # 触发外部回调

    # region 交互逻辑
    def _show_completer_popup(self) -> None:
        """点击 ▼ 时显示全部历史；键盘输入仍走正常过滤"""
        self._line_edit.setFocus()
        # 保存原过滤模式
        old_mode = self._completer.filterMode()
        # 临时改成“不过滤”
        self._completer.setFilterMode(Qt.MatchRegExp)
        self._completer.setCompletionPrefix(".*")
        self._completer.complete()
        # 立即恢复，以免影响后续键盘过滤
        self._completer.setFilterMode(old_mode)

    def _on_return_pressed(self) -> None:
        text = self._line_edit.text().strip()
        if not text:
            return

        # 1. 插到最前面
        if text in self._history:
            self._history.remove(text)
        self._history.insert(0, text)

        # 2. 控制最大条数（可选）
        max_items = 20
        if len(self._history) > max_items:
            self._history = self._history[:max_items]

        # 3. 刷新模型
        self._model.setStringList(self._history)

        # 4,update key
        self.update_key("recent", self._title, ",".join(self._history))

        # self._line_edit.clear()
        if self._callback:
            self._callback()

    # endregion

    # region 公开 API（与原接口保持一致）
    def setWidth(self, width: int) -> None:
        """设置整体宽度"""
        self._width = width
        self.setFixedWidth(width)
        self._line_edit.setFixedWidth(width - self._ARROW_BTN_WIDTH)

    def my_x(self):
        return self.x()

    def my_y(self):
        return self.y()

    def getWidth(self):
        return self._width

    def setCurrentText(self, text: str) -> None:
        self._line_edit.setText(text)

    def currentText(self) -> str:
        return self._line_edit.text()

    def hideWin(self) -> None:
        """隐藏下拉列表（QCompleter 自带 popup 会自动消失，这里留空即可）"""
        pass
    # endregion
